/**
 * Project 67th
 */


#include "ThreadPool.h"

/**
 * ThreadPool implementation
 */


/**
 * @param threadNum
 * @param queSize
 */
ThreadPool::ThreadPool(size_t threadNum, size_t queSize) 
: _threadNum(threadNum)
, _threads()
, _queSize(queSize)
, _taskQueue(_queSize)
, _isExit(false)
{

}

ThreadPool::~ThreadPool() {

}

/**
 * @return void
 */
void ThreadPool::start() {
    for(size_t idx = 0; idx < _threadNum; ++idx)
    {
        //要注意避免thread对象发生隐式的拷贝行为
        /* thread th(&ThreadPool::doTask,this); */
        /* _threads.push_back(std::move(th)); */

        _threads.push_back(thread(&ThreadPool::doTask,this));
    }
}

/**
 * @return void
 */
void ThreadPool::stop() {
    //如果任务队列不为空
    //那么主线程等待，
    //要等子线程把任务队列中所有的任务全都执行完
    //才去改动标志位（代表线程池退出）
    while(!_taskQueue.empty())
    {
        sleep(1);
    }

    //表示线程池要退出了
    _isExit = true;

    //此处_notEmpty是TaskQueue的私有成员、
    //可以做友元声明，护着TaskQueue添加公有的接口
    /* _taskQueue._notEmpty.notify_all(); */
    _taskQueue.wakeup();

    for(auto & ele : _threads)
    {
        ele.join();
    }
}

/**
 * @param pt
 * @return void
 */
void ThreadPool::addTask(ElemType pt) {
    if(pt)
    {
        _taskQueue.push(pt);
    }
    else
    {
        cout << "pt = nullptr" << endl;
    }
}

/**
 * @return ElemType
 */
ElemType ThreadPool::getTask() {
    return _taskQueue.pop();
}

/**
 * @return void
 */
void ThreadPool::doTask() {
    //如果线程池没有要退出
    //那么工作线程就应该一直工作
    while(!_isExit)
    {
        //如果发现任务队列为空，那么工作线程阻塞
        ElemType ptask = getTask();
        if(ptask)
        {
            /* ptask->process(); */
            ptask();
        }
        else
        {
            cout << "ptask = nullptr" << endl;
        }
    }
}
